package com.jwater.launch;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description:按照版本加载jar包，版本是"--时间戳"结尾来标识的
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public final class LoadVersionJar {
    public static final String VERSION_SPLIT = "--";

    /**
     * 获取最新版本的jar包
     *
     * @param dir
     * @param recursive 是否查找子目录
     * @return
     */
    public static List<File> currentVersionJar(File dir, boolean recursive) {
        List<File> list = new ArrayList<File>();
        if (dir == null || !dir.exists()) {
            return list;
        }
        listJars(list, dir, recursive);
        List<File> jarFiles = new ArrayList<File>();
        Map<String, List<JarFile>> group = groupByJarName(list);
        for (List<JarFile> jars : group.values()) {
            Collections.sort(jars, (o1, o2) -> -Long.compare(o1.version, o2.version));
            jarFiles.add(jars.get(0).file);
        }
        return jarFiles;
    }

    /**
     * 按照文件名对jar包分组
     *
     * @param files
     * @return
     */
    protected static Map<String, List<JarFile>> groupByJarName(List<File> files) {
        Map<String, List<JarFile>> group = new HashMap<String, List<JarFile>>();
        for (File file : files) {
            String name = file.getName();
            int index = name.lastIndexOf(".");
            name = name.substring(0, index);
            index = name.lastIndexOf(VERSION_SPLIT);
            String fileName = name;
            long version = -1;
            if (index > -1) {
                fileName = name.substring(0, index);
                try {
                    version = Long.parseLong(name.substring(index + 2));
                } catch (Exception e) {
                    version = -1;
                }
            }
            List<JarFile> list = group.get(fileName);
            if (list == null) {
                list = new ArrayList<JarFile>();
                group.put(fileName, list);
            }
            JarFile jarFile = new JarFile();
            jarFile.file = file;
            jarFile.name = fileName;
            jarFile.version = version;
            list.add(jarFile);
        }
        return group;
    }

    /**
     * 罗列目录下所有版本的jar包
     *
     * @param list
     * @param dir
     * @param recursive
     */
    protected static void listJars(List<File> list, File dir, boolean recursive) {
        File[] jarFiles = dir.listFiles();
        for (File jarFile : jarFiles) {
            if (jarFile.isDirectory()) {
                if (recursive) {
                    listJars(list, jarFile, recursive);
                }
            } else if (jarFile.getName().endsWith(".jar")) {
                list.add(jarFile);
            }
        }
    }

    /**
     * 加载最新版本的jar包
     *
     * @param dir
     * @param recursive
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws IOException
     */
    public static void loadCurrentVersionJar(File dir, boolean recursive)
            throws IllegalArgumentException, IllegalAccessException, IOException {
        List<File> jars = currentVersionJar(dir, recursive);
        for (File jar : jars) {
            LoadJar.loadJarFile(jar);
        }
    }

    protected static class JarFile {
        protected File file;
        protected String name;
        protected long version;

        @Override
        public String toString() {
            return "JarFile [file=" + file + ", name=" + name + ", version=" + version + "]";
        }
    }
}
